package com.ysyx.ysyx_nowtrack.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sun.org.apache.bcel.internal.generic.I2F;
import com.ysyx.ysyx_nowtrack.dto.BaseDto;
import com.ysyx.ysyx_nowtrack.pojo.TrackPojo;
import com.ysyx.ysyx_nowtrack.qo.OrderinfQo;
import com.ysyx.ysyx_nowtrack.qo.ReadOrderTrackQo;
import com.ysyx.ysyx_nowtrack.service.TrackPojoService;
import com.ysyx.ysyx_nowtrack.mapper.TrackPojoMapper;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.GeoEntry;
import org.redisson.api.RGeo;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @author 薛宇晖
* @description 针对表【track_inf(轨迹表)】的数据库操作Service实现
* @createDate 2023-04-12 14:45:40
*/
@Service
public class TrackPojoServiceImpl
    implements TrackPojoService{

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private TrackPojoMapper trackPojoMapper;

    @Override
    public BaseDto writeTrack(OrderinfQo qo) {

        BaseDto baseDto = new BaseDto();

        //开始判断订单状态 接口升级2.0
        RMap<Object, Object> map = redissonClient.getMap("orderinfo:" + qo.getOrderId());
        String orderStatus = (String) map.get("orderStatus");
//        乘客获取司机定位 订单状态码(订单状态码，注意非接口业务状态码)
//        乘客下单成功，等待系统派单	101
//        订单长时间没有司机接单,乘客取消订单	201
//        订单第一次过期，系统强制派单	202
//        订单第一次过期，系统强制派单失败（附近没有司机）	203
//
//        订单已分配司机，司机前往起点中	301
//        司机前往起点，乘客取消订单	302
        if (orderStatus.equals("302")) {
            return new BaseDto(302,"乘客取消订单",null);
        }
//        司机前往起点，司机取消订单	303
        if (orderStatus.equals("304")) {
            return new BaseDto(304,"被司机取消",null);
        }
//        司机前往起点时间过长	304
//
//        司机到达起点，等待乘客	401
//        司机到达起点，乘客长时间不上车/规定时间没有确认后四位	402
//        司机到达起点，确认乘客成功，开始行程	403
//
//        订单行程中(已废弃，请使用403)	501
//        订单行程中，订单被乘客取消	502
//        订单行程中，订单被司机取消	503
//        订单行程中，乘客重新选择终点	504
//        订单行程中，司机没有按照导航行驶	505
//        订单行程中，司机多次没有按照导航行驶	506
//        订单行程中，司机多次没有按照导航行驶，平台介入	507
//
//        司机到达终点，点击完成订单，行程结束，订单未被支付	601
//        司机到达终点，长时间没有点击完成订单	602
        if (orderStatus.equals("602")) {
            return new BaseDto(602,"到达终点不点完成订单",null);
        }
//        行程结束，订单被支付	603
        if (orderStatus.equals("603")) {
            return new BaseDto(603,"行程结束完成订单",null);
        }

        RGeo<Object> geo = redissonClient.getGeo("order:track:" + qo.getOrderId());
        Date date = new Date();
        //添加到redisson的订单geo桶中
//        redissonClient.getBucket(String.valueOf(date.getTime())).set(String.valueOf(date.getTime()));

        geo.add(new GeoEntry(qo.getLongitude(),qo.getLatitude(),date.getTime()));


        qo.setDate(date);
        String s = JSON.toJSONString(qo);





        return new BaseDto(Integer.valueOf(orderStatus),"请看状态码",null);
    }


    /*
     * @Description: (作用) mq 写入轨迹库
     * @params: qo   orderid  geo经纬度
     * @return:  无
     * @Author: 薛宇晖
     * @create:2023/4/12
     */
    @DS("track_1")
    public void mqWriteTrack(String orderId){
        System.out.println("进来了");
        System.err.println(orderId);
        RGeo<String> geo = redissonClient.getGeo("order:track:" + orderId);
        List<TrackPojo> trackPojos = new ArrayList<>();
        for (String o : geo) {

            double longitude = geo.pos(o).get(o).getLongitude();
            double latitude = geo.pos(o).get(o).getLatitude();
            System.err.println(latitude);
            TrackPojo trackPojo = new TrackPojo(null,orderId,longitude,latitude,new Date(Long.parseLong(o)));
            trackPojos.add(trackPojo);
        }

        trackPojoMapper.insertAllByOrderId(trackPojos);


//        TrackPojo trackPojo = new TrackPojo(null,qo.getOrderId(),qo.getLongitude(),qo.getLatitude(),qo.getDate());
//        trackPojoMapper.insert(trackPojo);

    }

    @Override
    public void pushDriverPoint(OrderinfQo qo) {

        String areaName = "";

        List<RMap<Object,Object>> maps = new ArrayList<>();


        RMap<Object, Object> mapA1 = redissonClient.getMap("area:A1");
        RMap<Object, Object> mapA2 = redissonClient.getMap("area:A2");
        RMap<Object, Object> mapA3 = redissonClient.getMap("area:A3");
        RMap<Object, Object> mapB1 = redissonClient.getMap("area:B1");
        RMap<Object, Object> mapB2 = redissonClient.getMap("area:B2");
        RMap<Object, Object> mapB3 = redissonClient.getMap("area:B3");
        maps.add(mapA1);
        maps.add(mapA2);
        maps.add(mapA3);
        maps.add(mapB1);
        maps.add(mapB2);
        maps.add(mapB3);

        //判断司机的位置
        for (RMap<Object, Object> map : maps) {

            String  theArea = map.getName();
            if (redissonClient.getGeo(theArea+"drivers").pos(qo.getDriverId()).get(qo.getDriverId())!=null){
                //每个地区池子去判断删除之前的地理信息
                boolean remove = redissonClient.getGeo(theArea + "drivers").remove(qo.getDriverId());
                    if (remove)break;
            }
        }


        //判断司机的位置
        for (RMap<Object, Object> map : maps) {

            Double leftupLongitude = Double.parseDouble((String) map.get("leftupLongitude")) ;
            Double leftupLatitude = Double.parseDouble((String) map.get("leftupLatitude")) ;
            Double rightdownLongitude = Double.parseDouble((String) map.get("rightdownLongitude")) ;
            Double rightdownLatitude = Double.parseDouble((String) map.get("rightdownLatitude")) ;
            if (qo.getLongitude()>=leftupLongitude &&   //司机位置经度 >= 区域左上经度
                    qo.getLongitude()<=rightdownLongitude &&  //司机位置经度 <= 区域右下经度
                    qo.getLatitude()>=rightdownLatitude &&// 司机位置纬度 >= 区域右下纬度
                    qo.getLatitude()<=leftupLatitude// 司机位置纬度 >= 区域左上纬度
            )
            {
                areaName =  map.getName();
                break;
            }else {
                continue;
            }
        }
        //获取到司机所在地区的名称 areaname
        System.out.println(areaName);

        RGeo<String> geo = redissonClient.getGeo(areaName+":drivers");
        geo.add(new GeoEntry(qo.getLongitude(),qo.getLatitude(),qo.getDriverId()));

    }

    @Override
    @DS(value = "track_1")
    public BaseDto getOrderHistory(String orderId) {

        QueryWrapper<TrackPojo> trackQw = new QueryWrapper<>();
        trackQw.eq("order_id",orderId);
        List<TrackPojo> tracklist = trackPojoMapper.selectList(trackQw);

        tracklist.stream().forEach(System.out::println);

        if(tracklist.size()>0){

            List<ReadOrderTrackQo> readOrderTrackList = new ArrayList<>();

            for(int i = 0 ; i < tracklist.size() ; i ++){
                ReadOrderTrackQo tempReadOrderTrackQo = new ReadOrderTrackQo();
                tempReadOrderTrackQo.setX(tracklist.get(i).getLongitude());
                tempReadOrderTrackQo.setY(tracklist.get(i).getLatitude());
                tempReadOrderTrackQo.setTm(i+1);
                tempReadOrderTrackQo.setSp(0);
                tempReadOrderTrackQo.setAg(0);

                readOrderTrackList.add(tempReadOrderTrackQo);
            }

            return new BaseDto(100,"查询成功",readOrderTrackList);
        }else{
            return new BaseDto(200,"系统错误,请确认订单",null);
        }



    }
}




